package com.example.camerafacedetect.faceframe;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.PointF;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Range;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

import com.example.camerafacedetect.R;
import com.google.mlkit.vision.face.Face;

import java.io.IOException;
import java.util.List;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {

    private Context context;
    private Camera camera;
    private FaceView faceView;

    private OnFaceDetectedListener onFaceDetectedListener;

    /**
     * 摄像头最大的预览尺寸
     */
    private Size maxPreviewSize;

    /**
     * 预览时Frame的计数器
     */
    private int frameCount;

    public CameraView(Context context) {
        super(context);
        init(context);
    }

    public CameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        this.context = context;
        getHolder().addCallback(this);
    }

    public void setFaceView(FaceView faceView) {
        if (faceView != null) {
            this.faceView = faceView;
        }
    }

    /** 摄像头重新开始预览 */
    public void reset() {
        if(faceView != null) {
            faceView.setVisibility(View.GONE);
        }
        if(camera != null) {
            camera.setPreviewCallback(this);
            camera.startPreview();
        }
        frameCount = 0;
    }

    public void pause(){
        camera.stopPreview();
    }

    // 这个函数是在surface首次被创建的时候调用的
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            CameraManager cameraManager = (CameraManager) this.context.getSystemService(Context.CAMERA_SERVICE);
            //获得某个摄像头的特征，支持的参数
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics("0");
            int[] values = characteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES);
            Log.e("", "++++++ output SCENE_MODES ++++++");
            for(int i = 0; i< values.length; i++){
                Log.e("++++++++++++++ ", "scene value is: " + values[i]);
            }

            values = characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
            Log.e("","++++++ output FACE_DETECT_MODES ++++++");
            for(int i = 0; i< values.length; i++){
                Log.e("++++++++++++++ ", "face detect value is: " + values[i]);
            }

            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            if(camera != null) {
                camera.setDisplayOrientation(90);
                // camera必须要绑定一个view（surfaceview）用于做预览展示
                camera.setPreviewDisplay(holder);
                camera.setPreviewCallback(this);
            }
        } catch (IOException | CameraAccessException e) {
            e.printStackTrace();
        }
    }
    // 每次摄像头采集到图片的大小（size）或者格式（format）的时候触发
    // 这个事件将会至少被调用一次，即suraceCreate之后，会被触发；之后只有图片格式或者大小发生变化了才会被触发
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (camera != null) {
            maxPreviewSize = getMaxPreviewSize(camera);
            if (maxPreviewSize != null) {
                ViewGroup.LayoutParams params = getLayoutParams();
                Point point = getScreenSize();
                params.width = point.x;
                params.height = maxPreviewSize.width * point.x / maxPreviewSize.height;
                setLayoutParams(params);
                if(faceView != null) {
                    faceView.setLayoutParams(params);
                }
                Camera.Parameters parameters = camera.getParameters();
                parameters.setPreviewSize(maxPreviewSize.width, maxPreviewSize.height);
                camera.setParameters(parameters);
            }
            camera.startPreview();
            frameCount = 0;
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (camera != null) {
            try {
                camera.stopPreview();
                camera.setPreviewDisplay(null);
                camera.setPreviewCallback(null);
                camera.release();
                camera = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取手机屏幕的尺寸
     *
     * @return
     */
    private Point getScreenSize() {
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(outMetrics);
        return new Point(outMetrics.widthPixels, outMetrics.heightPixels);
    }

    /**
     * 获取摄像头最大的预览尺寸
     *
     * @param camera
     * @return
     */
    private Size getMaxPreviewSize(Camera camera) {
        List<Size> list = camera.getParameters().getSupportedPreviewSizes();
        if (list != null) {
            int max = 0;
            Size maxSize = null;
            for (Size size : list) {
                int n = size.width * size.height;
                if (n > max) {
                    max = n;
                    maxSize = size;
                }
            }
            return maxSize;
        }
        return null;
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        Log.e("yubo", "onPreviewFrame..." + "pasuse_flag: " + GlobalVariable.pause_flag
                +"; bitmap queue size: " + GlobalVariable.bitmap_queue.size());
        // 系统标志位暂停，则不再做任何处理
        if(GlobalVariable.pause_flag){
            return;
        }
        // 如果现在队列中的数据已经超过指定个数，则不再向队列中插入图像，跳过当前帧
        if(GlobalVariable.bitmap_queue.size() >= GlobalVariable.BITMAP_QUEUE_MAX){
            return;
//            GlobalVariable.bitmap_queue.clear();
        }
        Size size = camera.getParameters().getPreviewSize();
        final byte[] byteArray = ImageUtils.yuv2Jpeg(data, size.width, size.height);
        Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
        // TODO 是否可以不用copy直接获得一个isMutable
        bitmap = bitmap.copy(Bitmap.Config.RGB_565, true);
        GlobalVariable.bitmap_queue.offer(bitmap);
    }


    /**
     * 检测到人脸的监听器
     */
    public interface OnFaceDetectedListener {
        void onFaceDetected(Bitmap bm);
    }

    /**
     * 设置监听器，监听检测到人脸的动作
     */
    public void setOnFaceDetectedListener(OnFaceDetectedListener listener) {
        if (listener != null) {
            this.onFaceDetectedListener = listener;
        }
    }

}